﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

using Microsoft.SqlServer.Management.Smo;

using SQLDataTransferer.Model;

namespace SQLDataTransferer.ViewModel
{
    public class TransferViewModel : SmoViewModelBase
    {
        #region Fields

        RelayCommand _targetServersRefreshCommand;
        RelayCommand _targetDatabasesRefreshCommand;
        RelayCommand _transferCommand;

        #endregion

        #region Constructor(s)

        public TransferViewModel(string displayName, System.Globalization.CultureInfo culture, Dispatcher dispatcher, Window main)
            : base(displayName, culture, dispatcher, main)
        {
            //this.DestinationServers = new ObservableCollection<Model.SqlInstance>();

            //this.DestinationDatabases = new ObservableCollection<Database>();
        }

        #endregion

        #region Properties

        RadioButtonOptions _currentOptionDestination = RadioButtonOptions.Windows;
        /// <summary>
        /// Used as workaround for the radiobuttons databinding
        /// </summary>
        public RadioButtonOptions CurrentOptionDestination
        {
            get { return this._currentOptionDestination; }
            set
            {
                this._currentOptionDestination = value;
                this.OnPropertyChanged("CurrentOptionDestination");
            }
        }

        public IList<SqlInstance> TargetServers { get; set; }

        public IList<Database> TargetDatabases { get; set; }

        public SqlInstance SelectedServer_target { get; set; }

        public Database SelectedDb_target { get; set; }

        #region Commands

        public ICommand TargetServersRefreshCommand
        {
            get
            {
                if (this._targetServersRefreshCommand == null)
                    this._targetServersRefreshCommand = new RelayCommand((o) => this.OnTargetServersRefresh());

                return this._targetServersRefreshCommand;
            }
        }

        public ICommand TargetDatabasesRefreshCommand
        {
            get
            {
                if (this._targetDatabasesRefreshCommand == null)
                    this._targetDatabasesRefreshCommand = new RelayCommand((o) => this.OnTargetDatabasesRefresh());

                return this._targetDatabasesRefreshCommand;
            }
        }

        public ICommand TransferCommand
        {
            get
            {
                if (this._transferCommand == null)
                    this._transferCommand = new RelayCommand((o) => this.OnTransfer());

                return this._transferCommand;
            }
        }

        #endregion

        #endregion

        #region Methods

        /// <summary>
        /// Exectutes the actual code for retrieving/refreching a list of server instances
        /// </summary>
        /// <returns></returns>
        private void OnTargetServersRefresh()
        {
            this.RunTaskDialog("Refreshing Servers ...",
                () =>
                {
                    this.TargetServers = base.LoadServers();
                    this.OnPropertyChanged("TargetServers");
                }); //TODO: resources                  
        }

        /// <summary>
        /// Exectutes the actual code for retrieving/refreching a list of database from the current selected target db server
        /// </summary>
        /// <returns></returns>
        private void OnTargetDatabasesRefresh()
        {
            this.RunTaskDialog("Refreshing Databases ...",
                () =>
                {
                    this.TargetDatabases = base.LoadDatabases(this.SelectedServer_target, this.CurrentOptionDestination == RadioButtonOptions.Windows);
                    this.OnPropertyChanged("TargetDatabases");
                }); //TODO: resources
        }

        /// <summary>
        /// Executes the actual code for transfering the data between databases/servers
        /// </summary>
        private void OnTransfer()
        {
            this.SetFocus();

            this.RunTaskDialog("Transfering data ...", 
                () => 
                {
                    //#region Validation

                    //this.Status = "Validating input ..."; //TODO: Translate
                    //System.Threading.Thread.Sleep(500); // Make sure the user sees the current status

                    //System.Text.StringBuilder sb = new System.Text.StringBuilder(0);
                    //if (this.SelectedHostInstance == null)
                    //    sb.AppendLine("You must select/provide an host server."); //TODO: Translate

                    //if (this.SelectedHostDatabase == null ||
                    //    string.IsNullOrEmpty(this.SelectedHostDatabase.Name))
                    //    sb.AppendLine("You must select/provide an host database."); //TODO: Translate

                    //if (this.SelectedDestinationInstance == null)
                    //    sb.AppendLine("You must select/provide an destination server."); //TODO: Translate

                    //if (this.SelectedDestinationDatabase == null ||
                    //    string.IsNullOrEmpty(this.SelectedDestinationDatabase.Name))
                    //    sb.AppendLine("You must select/provide an destination database."); //TODO: Translate

                    //#endregion

                    //if (sb.Length > 0)
                    //    this.Status = sb.Insert(0, "Warning:\r\n").ToString(); //TODO: Translate
                    //else
                    //{
                    //    // Validation passed
                    //    this.Status = "Validation passed."; // TODO: Translate
                    //    System.Threading.Thread.Sleep(300); // Make sure the user sees the current status

                    //    // Start actual transfer
                    //    this.Status = "Transfering ..."; //TODO: Translate

                    //    this.CurrentServer = new Server(this.SelectedHostInstance.FullName);

                    //    if (this.CurrentOptionDestination == RadioButtonOptions.Sql)
                    //        this.CurrentDestinationServer = SmoFactory.GetServer(SmoFactory.CreateConnection(this.SelectedDestinationInstance.FullName, this.DestinationSqlUserName, this.DestinationSqlPassword));
                    //    else
                    //        this.CurrentDestinationServer = SmoFactory.GetServer(SmoFactory.CreateConnection(this.SelectedDestinationInstance.FullName));

                    //    // Set the parent for the database (owner server)
                    //    try { this.SelectedDestinationDatabase.Parent = this.CurrentDestinationServer; }
                    //    catch
                    //    {
                    //        // if database is allready member of a collection, there is a exception (database's parent is not null)
                    //        this.SelectedDestinationDatabase =
                    //            new Database(this.CurrentDestinationServer, this.SelectedDestinationDatabase.Name);
                    //    }

                    //    // Get the startTime
                    //    TimeSpan startTime = DateTime.Now.TimeOfDay;

                    //    // Define the location of the DataFile + log to create (*.mdf & *.ldf)
                    //    string dataFileLocation = System.IO.Path.Combine(this.SelectedHostDatabase.PrimaryFilePath,
                    //        string.Format(@"Conversie\{0} - {1}",
                    //        this.SelectedHostDatabase.Parent.InstanceName,
                    //        this.CurrentDestinationServer.InstanceName));

                    //    // Check directory, if not exist -> create
                    //    if (!System.IO.Directory.Exists(dataFileLocation))
                    //        System.IO.Directory.CreateDirectory(dataFileLocation);

                    //    // Register event, to notify the user with the current state
                    //    SmoFactory.TransferProgress += new SmoFactory.TransferProgressEventHandler(SmoFactory_TransferProgress);
                    //    // Start tranfer using SMO                
                    //    SmoFactory.TransferDatabase(this.SelectedHostDatabase.Parent, this.SelectedHostDatabase, this.CurrentDestinationServer, this.SelectedDestinationDatabase, dataFileLocation);

                    //    // Get the time spend for the current operation
                    //    TimeSpan duration = DateTime.Now.TimeOfDay - startTime;

                    //    sb = new System.Text.StringBuilder("Transfer has been completed.").AppendLine(); //TODO: Translate                
                    //    sb.Append("The current operation has taken");
                    //    sb.AppendFormat(" {0} Hours", duration.Hours);
                    //    sb.AppendFormat(", {0} Minutes", duration.Minutes);
                    //    sb.AppendFormat(", {0} Seconds", duration.Seconds);

                    //    this.Status = sb.ToString();

                    //    sb = null;

                    //    // Make sure the databases are cleared after tranfer
                    //    ProgressHelper.ClearDataSource(this.DestinationDatabases, this.DispatcherObject);
                    //}
                }); //TODO: resources
        }

        private void OnTransfer_Internal()
        {
            this.SetFocus();

            this.RunTaskDialog("Transfering data ...",
                () =>
                {
                    //TODO: Validation of input

                    var sSrv = this.SelectedServer;
                    var sDb = this.SelectedDb;

                    var tSrv = this.SelectedServer_target;
                    var tDb = this.SelectedDb_target;

                    Server srv = null;

                    if (this.CurrentOptionDestination == RadioButtonOptions.Sql)
                        srv = SmoFactory.GetServer(SmoFactory.CreateConnection(tSrv.FullName, "username", "password"));
                    else
                        srv = SmoFactory.GetServer(SmoFactory.CreateConnection(tSrv.FullName));

                    //tDb.Parent = srv;

                    // Set the parent for the database (owner server)
                    try { tDb.Parent = srv; }
                    catch
                    {
                        // if database is allready member of a collection, there is a exception (database's parent is not null)
                        tDb = new Database(srv, "test");
                    }

                    // Get the startTime
                    TimeSpan startTime = DateTime.Now.TimeOfDay;

                    // Define the location of the DataFile + log to create (*.mdf & *.ldf)
                    string dataFileLocation = System.IO.Path.Combine(this.SelectedDb_target.PrimaryFilePath,
                        string.Format(@"Conversie\{0} - {1}",
                        this.SelectedDb_target.Parent.InstanceName,
                        tSrv.InstanceName));

                    // Check directory, if not exist -> create
                    if (!System.IO.Directory.Exists(dataFileLocation))
                        System.IO.Directory.CreateDirectory(dataFileLocation);

                    //    // Register event, to notify the user with the current state
                    //    SmoFactory.TransferProgress += new SmoFactory.TransferProgressEventHandler(SmoFactory_TransferProgress);
                    //    // Start tranfer using SMO                
                    //    SmoFactory.TransferDatabase(this.SelectedHostDatabase.Parent, this.SelectedHostDatabase, this.CurrentDestinationServer, this.SelectedDestinationDatabase, dataFileLocation);

                    //    // Get the time spend for the current operation
                    //    TimeSpan duration = DateTime.Now.TimeOfDay - startTime;

                    //    sb = new System.Text.StringBuilder("Transfer has been completed.").AppendLine(); //TODO: Translate                
                    //    sb.Append("The current operation has taken");
                    //    sb.AppendFormat(" {0} Hours", duration.Hours);
                    //    sb.AppendFormat(", {0} Minutes", duration.Minutes);
                    //    sb.AppendFormat(", {0} Seconds", duration.Seconds);

                    //    this.Status = sb.ToString();

                    //    sb = null;

                    //    // Make sure the databases are cleared after tranfer
                    //    ProgressHelper.ClearDataSource(this.DestinationDatabases, this.DispatcherObject);
                    //}
                }); //TODO: resources
        }

        #endregion
    }
}
